package com.own.stu.apm.plugins.mysql;

import com.own.stu.apm.agent.core.plugin.AbstractClassEnhencePluginDefine;
import com.own.stu.apm.agent.core.plugin.interceptor.ConstructorMethodsInterceptorPoint;
import com.own.stu.apm.agent.core.plugin.interceptor.InstanceMethodsInterceptorPoint;
import com.own.stu.apm.agent.core.plugin.interceptor.StaticMethodsInterceptorPoint;
import com.own.stu.apm.agent.core.plugin.interceptor.enhence.ClassEnhancePluginDefine;
import com.own.stu.apm.agent.core.plugin.match.ClassMatch;
import com.own.stu.apm.agent.core.plugin.match.NameMatch;
import net.bytebuddy.description.method.MethodDescription;
import net.bytebuddy.matcher.ElementMatcher;
import net.bytebuddy.matcher.ElementMatchers;

import static net.bytebuddy.matcher.ElementMatchers.named;

public class MysqlInstrumentation extends ClassEnhancePluginDefine {

    private static final String CLIENT_PS_NAME = "com.mysql.cj.jdbc.ClientPreparedStatement";
    private static final String SERVER_PS_NAME = "com.mysql.cj.jdbc.ServerPreparedStatement";
    private static final String INTERCEPTOR = "com.own.stu.apm.plugins.mysql.interceptor.MysqlInterceptor";

    protected ClassMatch enhanceClass() {
        return NameMatch.byClassName(INTERCEPTOR);
    }

    protected InstanceMethodsInterceptorPoint[] getInstanceMethodsInterceptorPoint() {
        return new InstanceMethodsInterceptorPoint[]{
                new InstanceMethodsInterceptorPoint() {

                    public ElementMatcher<MethodDescription> getMethodMatcher() {
                        return named("execute")
                                .or(ElementMatchers.<MethodDescription>named(CLIENT_PS_NAME)
                                        .or(ElementMatchers.<MethodDescription>named(SERVER_PS_NAME)));
                    }

                    public String getMethodInterceptor() {
                        return INTERCEPTOR;
                    }
                }
        };
    }

    protected ConstructorMethodsInterceptorPoint[] getConstructorMethodsInterceptorPoint() {
        return new ConstructorMethodsInterceptorPoint[0];
    }

    protected StaticMethodsInterceptorPoint[] getStaticMethodsInterceptorPoint() {
        return new StaticMethodsInterceptorPoint[0];
    }
}
